Spring Gateway
网关不转发,直接返回
import com.alibaba.cloud.nacos.discovery.NacosDiscoveryClient;
import com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.http.HttpUtil;
import org.dromara.hutool.json.JSONArray;
import org.dromara.hutool.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import java.io.IOException;
import java.util.List;
/**
* 路由配置信息
*/
@Slf4j
@Configuration
public class HealthCheckConfiguration {
private final List<String> ALL_SERVICE = List.of(
"comprehensive-budget",
"core-risk",
"electric-charge",
"financial-health",
"government-enterprise",
"grid-allocation",
"private-enterprise",
"province-sign",
"smart-finance"
);
@Autowired
private NacosServiceDiscovery nacosServiceDiscovery;
@SuppressWarnings("rawtypes")
@Bean
public RouterFunction routerFunction() {
return RouterFunctions.route(
RequestPredicates.GET("/health/check")
.and(RequestPredicates.accept(MediaType.APPLICATION_JSON)),
(ServerRequest serverRequest) -> {
MultiValueMap<String, String> queryParams = serverRequest.exchange().getRequest().getQueryParams();
List<String> nameList = queryParams.get("serviceName");
if (CollUtil.isEmpty(nameList)) {
return ServerResponse.status(HttpStatus.BAD_REQUEST)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue("serviceName is required, please input serviceName parameter from query string"));
}
String name = nameList.get(0);
JSONObject entries = serviceStatus(name);
if (entries == null) {
return ServerResponse.status(HttpStatus.SERVICE_UNAVAILABLE).build();
} else {
if (entries.get("isHealthy").equals(true)) {
return ServerResponse.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(serviceStatus(name)));
} else {
return ServerResponse.status(HttpStatus.SERVICE_UNAVAILABLE).build();
}
}
});
}
public JSONObject serviceStatus(String name) {
JSONArray healthy = healthy();
for (Object o : healthy) {
JSONObject jsonObject = (JSONObject) o;
if (!jsonObject.getStr("serviceName").equals(name)) {
continue;
}
return jsonObject;
}
return null;
}
/**
* 获取服务信息
* @return
*/
public JSONArray healthy() {
NacosDiscoveryClient nacosDiscoveryClient = new NacosDiscoveryClient(nacosServiceDiscovery);
JSONArray jsonArray = new JSONArray();
for (String service : ALL_SERVICE) {
JSONObject entries = new JSONObject();
List<ServiceInstance> instances = nacosDiscoveryClient.getInstances(service);
if (CollUtil.isEmpty(instances)) {
entries.put("serviceName", service);
entries.put("isHealthy", false);
} else {
for (ServiceInstance serviceInstance : instances) {
String s = HttpUtil.get(serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/actuator/health");
JSONObject resp = new JSONObject(s);
Object status = resp.get("status");
if (status==null){
entries.put("serviceName", serviceInstance.getServiceId());
entries.put("isHealthy", false);
continue;
}
if (status.equals(404)) {
entries.put("serviceName", serviceInstance.getServiceId());
entries.put("isHealthy", false);
} else if (status.equals("UP")) {
entries.put("serviceName", serviceInstance.getServiceId());
entries.put("isHealthy", true);
break;
}
}
}
jsonArray.add(entries);
}
return jsonArray;
}
}